import 'dart:async';

import 'package:flame/collisions.dart';
import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flame/palette.dart';
import 'package:flame_spine/flame_spine.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'PlayerStateComponent2.dart';

class PlayerComponent2 extends RectangleComponent
    with CollisionCallbacks, KeyboardHandler {

  late final SpineComponent spineboy;

  final states = [
    'walk',
    'aim',
    'death',
    'hoverboard',
    'idle',
    'jump',
    'portal',
    'run',
    'shoot',
  ];

  static const speed = 100.0;
  static const squareSize = 32.0;
  static Paint magenta = BasicPalette.magenta.paint();
  final double _speed = 100;
  final Vector2 _direction = Vector2.zero();
  Vector2? moveTarget;
  List<Vector2>? moveTargetList;
  int currentWaypointIndex = 0;

  late PlayerStateComponent2 state;

  PlayerComponent2(Vector2 position)
      : super(position: position, anchor: Anchor.center);

  @override
  Future<void> onLoad() async {
    super.onLoad();
    var hitbox = RectangleHitbox(size: Vector2.all(squareSize));
    add(hitbox);
    hitbox.debugMode = true;
    hitbox.debugColor = Colors.tealAccent;
    state = PlayerStateComponent2(Vector2.all(squareSize));
    state.loadIdleState(0.2);
    add(state);
  }

  @override
  bool onKeyEvent(KeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
    //print("event=$event");
    if (event is KeyDownEvent) {
      state.resetState();
      switch (event.logicalKey) {
        case LogicalKeyboardKey.arrowUp:
          {
            if (!state.isAttack()) {
              _direction.y += -1;
              state.loadRunState(0.1);
            }
            //print("_direction.y=${_direction.y}");
          }
        case LogicalKeyboardKey.arrowDown:
          {
            if (!state.isAttack()) {
              _direction.y += 1;
              state.loadRunState(0.1);
            }
            //print("_direction.y=${_direction.y}");
          }
        case LogicalKeyboardKey.arrowLeft:
          {
            if (!state.isAttack()) {
              _direction.x += -1;
              state.loadRunState(0.1);
              if (!state.isFlippedHorizontally) {
                state.flipHorizontallyAroundCenter();
              }
            }
            //print("_direction.x=${_direction.x}");
          }
        case LogicalKeyboardKey.arrowRight:
          {
            if (!state.isAttack()) {
              _direction.x += 1;
              state.loadRunState(0.1);
              if (state.isFlippedHorizontally) {
                state.flipHorizontallyAroundCenter();
              }
            }
            //print("_direction.x=${_direction.x}");
          }
        case LogicalKeyboardKey.shiftLeft:
          {
            state.loadAttackState(0.2);
          }
      }
    }
    if (event is KeyUpEvent) {
      switch (event.logicalKey) {
        case LogicalKeyboardKey.arrowUp:
        case LogicalKeyboardKey.arrowDown:
          {
            state.loadIdleState(0.2);
            _direction.y = 0;
            //print("_direction.y=${_direction.y}");
          }
        case LogicalKeyboardKey.arrowLeft:
        case LogicalKeyboardKey.arrowRight:
          {
            state.loadIdleState(0.2);
            _direction.x = 0;
            //print("_direction.x=${_direction.x}");
          }
      }
    }
    return super.onKeyEvent(event, keysPressed);
  }

  @override
  void update(double dt) {
    //print("position=$position");
    if (_direction.x != 0 || _direction.y != 0) {
      moveTarget = null; //只要动了方向键,就不要再向鼠标移动
      final displacement = _direction.normalized() * speed * dt;
      position.add(displacement);
    } else if (moveTarget != null) {
      if (moveTarget!.distanceTo(position) > 2) {
        var dir = (moveTarget! - position).normalized();
        position.addScaled(dir * speed, dt);
      } else {
        moveTarget = null;
        currentWaypointIndex++;
      }
    } else if (moveTargetList != null) {
      if (currentWaypointIndex < moveTargetList!.length) {
        moveTarget = moveTargetList![currentWaypointIndex];
        if (moveTarget!.distanceTo(position) > 2) {
          var dir = (moveTarget! - position).normalized();
          //print("dir=${dir}");
          if (dir.x > 0) {
            if (state.isFlippedHorizontally) {
              state.flipHorizontallyAroundCenter();
            }
          } else {
            if (!state.isFlippedHorizontally) {
              state.flipHorizontallyAroundCenter();
            }
          }
          state.loadRunState(0.1);
          position.addScaled(dir * speed, dt);
        } else {
          moveTarget = null;
          currentWaypointIndex++;
        }
      } else {
        moveTargetList = null;
        currentWaypointIndex = 0;
        state.loadIdleState(0.2);
      }
    }
    super.update(dt);
  }

  void moveTowardsNextPoint() {}

  @override
  void onCollisionStart(Set<Vector2> _, PositionComponent other) {
    print("other=${other.toString()}");
    super.onCollisionStart(_, other);
  }

  void stop() {
    moveTarget = null;
  }

  void moveTo(Vector2 target) {
    currentWaypointIndex = 0;
    moveTargetList = null;
    moveTarget = target;
  }

  Future<void> moveToList(Iterable<Vector2>? pathList) async {
    if (pathList != null && pathList.isNotEmpty) {
      try {
        currentWaypointIndex = 0;
        moveTargetList = pathList.toList();
        state.loadRunState(0.1);
      } catch (e) {
        // 错误处理
        print('Error during moveToList: $e');
      }
    }
  }

  void moveToEffect(Vector2 target) {
    double timeMs = (target - position).length / _speed;
    EffectController ctrl = EffectController(duration: timeMs);
    Effect effect = MoveToEffect(target, ctrl);
    add(effect);
  }
}
